mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
bpo-22257: Small changes for PEP 432. (#1728)
PEP 432 specifies a number of large changes to interpreter startup code, including exposing a cleaner C-API. The major changes depend on a number of smaller changes. This patch includes all those smaller changes.
This commit is contained in:
parent
f9169ce6b4
commit
6b4be195cd
19 changed files with 2221 additions and 2006 deletions
|
@ -533,44 +533,57 @@ _PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
|
|||
return pyurandom(buffer, size, 0, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_PyRandom_Init(void)
|
||||
int Py_ReadHashSeed(char *seed_text,
|
||||
int *use_hash_seed,
|
||||
unsigned long *hash_seed)
|
||||
{
|
||||
char *env;
|
||||
unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc;
|
||||
Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
|
||||
Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
|
||||
/* Convert a text seed to a numeric one */
|
||||
if (seed_text && *seed_text != '\0' && strcmp(seed_text, "random") != 0) {
|
||||
char *endptr = seed_text;
|
||||
unsigned long seed;
|
||||
seed = strtoul(seed_text, &endptr, 10);
|
||||
if (*endptr != '\0'
|
||||
|| seed > 4294967295UL
|
||||
|| (errno == ERANGE && seed == ULONG_MAX))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/* Use a specific hash */
|
||||
*use_hash_seed = 1;
|
||||
*hash_seed = seed;
|
||||
}
|
||||
else {
|
||||
/* Use a random hash */
|
||||
*use_hash_seed = 0;
|
||||
*hash_seed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_hash_secret(int use_hash_seed,
|
||||
unsigned long hash_seed)
|
||||
{
|
||||
void *secret = &_Py_HashSecret;
|
||||
Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
|
||||
|
||||
if (_Py_HashSecret_Initialized)
|
||||
return;
|
||||
_Py_HashSecret_Initialized = 1;
|
||||
|
||||
/*
|
||||
Hash randomization is enabled. Generate a per-process secret,
|
||||
using PYTHONHASHSEED if provided.
|
||||
*/
|
||||
|
||||
env = Py_GETENV("PYTHONHASHSEED");
|
||||
if (env && *env != '\0' && strcmp(env, "random") != 0) {
|
||||
char *endptr = env;
|
||||
unsigned long seed;
|
||||
seed = strtoul(env, &endptr, 10);
|
||||
if (*endptr != '\0'
|
||||
|| seed > 4294967295UL
|
||||
|| (errno == ERANGE && seed == ULONG_MAX))
|
||||
{
|
||||
Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
|
||||
"in range [0; 4294967295]");
|
||||
}
|
||||
if (seed == 0) {
|
||||
if (use_hash_seed) {
|
||||
if (hash_seed == 0) {
|
||||
/* disable the randomized hash */
|
||||
memset(secret, 0, secret_size);
|
||||
}
|
||||
else {
|
||||
lcg_urandom(seed, secret, secret_size);
|
||||
/* use the specified hash seed */
|
||||
lcg_urandom(hash_seed, secret, secret_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* use a random hash seed */
|
||||
int res;
|
||||
|
||||
/* _PyRandom_Init() is called very early in the Python initialization
|
||||
|
@ -586,7 +599,24 @@ _PyRandom_Init(void)
|
|||
}
|
||||
|
||||
void
|
||||
_PyRandom_Fini(void)
|
||||
_Py_HashRandomization_Init(void)
|
||||
{
|
||||
char *seed_text;
|
||||
int use_hash_seed = -1;
|
||||
unsigned long hash_seed;
|
||||
|
||||
if (use_hash_seed < 0) {
|
||||
seed_text = Py_GETENV("PYTHONHASHSEED");
|
||||
if (Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
|
||||
Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
|
||||
"in range [0; 4294967295]");
|
||||
}
|
||||
}
|
||||
init_hash_secret(use_hash_seed, hash_seed);
|
||||
}
|
||||
|
||||
void
|
||||
_Py_HashRandomization_Fini(void)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
if (hCryptProv) {
|
3584
Python/importlib.h
3584
Python/importlib.h
File diff suppressed because it is too large
Load diff
|
@ -291,6 +291,9 @@ import_init(PyInterpreterState *interp, PyObject *sysmod)
|
|||
|
||||
/* Install importlib as the implementation of import */
|
||||
value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
|
||||
if (value != NULL)
|
||||
value = PyObject_CallMethod(importlib,
|
||||
"_install_external_importers", "");
|
||||
if (value == NULL) {
|
||||
PyErr_Print();
|
||||
Py_FatalError("Py_Initialize: importlib install failed");
|
||||
|
@ -331,8 +334,8 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
|||
Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
|
||||
if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')
|
||||
Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p);
|
||||
/* The variable is only tested for existence here; _PyRandom_Init will
|
||||
check its value further. */
|
||||
/* The variable is only tested for existence here;
|
||||
_Py_HashRandomization_Init will check its value further. */
|
||||
if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
|
||||
Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p);
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -342,7 +345,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
|||
Py_LegacyWindowsStdioFlag = add_flag(Py_LegacyWindowsStdioFlag, p);
|
||||
#endif
|
||||
|
||||
_PyRandom_Init();
|
||||
_Py_HashRandomization_Init();
|
||||
|
||||
_PyInterpreterState_Init();
|
||||
interp = PyInterpreterState_New();
|
||||
|
@ -402,13 +405,15 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
|||
/* initialize builtin exceptions */
|
||||
_PyExc_Init(bimod);
|
||||
|
||||
sysmod = _PySys_Init();
|
||||
sysmod = _PySys_BeginInit();
|
||||
if (sysmod == NULL)
|
||||
Py_FatalError("Py_Initialize: can't initialize sys");
|
||||
interp->sysdict = PyModule_GetDict(sysmod);
|
||||
if (interp->sysdict == NULL)
|
||||
Py_FatalError("Py_Initialize: can't initialize sys dict");
|
||||
Py_INCREF(interp->sysdict);
|
||||
if (_PySys_EndInit(interp->sysdict) < 0)
|
||||
Py_FatalError("Py_Initialize: can't initialize sys");
|
||||
_PyImport_FixupBuiltin(sysmod, "sys");
|
||||
PySys_SetPath(Py_GetPath());
|
||||
PyDict_SetItemString(interp->sysdict, "modules",
|
||||
|
@ -694,7 +699,7 @@ Py_FinalizeEx(void)
|
|||
PyDict_Fini();
|
||||
PySlice_Fini();
|
||||
_PyGC_Fini();
|
||||
_PyRandom_Fini();
|
||||
_Py_HashRandomization_Fini();
|
||||
_PyArg_Fini();
|
||||
PyAsyncGen_Fini();
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
|
|||
/* The single PyInterpreterState used by this process'
|
||||
GILState implementation
|
||||
*/
|
||||
/* TODO: Given interp_main, it may be possible to kill this ref */
|
||||
static PyInterpreterState *autoInterpreterState = NULL;
|
||||
static int autoTLSkey = -1;
|
||||
#else
|
||||
|
@ -55,6 +56,7 @@ static int autoTLSkey = -1;
|
|||
#endif
|
||||
|
||||
static PyInterpreterState *interp_head = NULL;
|
||||
static PyInterpreterState *interp_main = NULL;
|
||||
|
||||
/* Assuming the current thread holds the GIL, this is the
|
||||
PyThreadState for the current thread. */
|
||||
|
@ -119,6 +121,9 @@ PyInterpreterState_New(void)
|
|||
|
||||
HEAD_LOCK();
|
||||
interp->next = interp_head;
|
||||
if (interp_main == NULL) {
|
||||
interp_main = interp;
|
||||
}
|
||||
interp_head = interp;
|
||||
if (_next_interp_id < 0) {
|
||||
/* overflow or Py_Initialize() not called! */
|
||||
|
@ -185,6 +190,11 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
|
|||
if (interp->tstate_head != NULL)
|
||||
Py_FatalError("PyInterpreterState_Delete: remaining threads");
|
||||
*p = interp->next;
|
||||
if (interp_main == interp) {
|
||||
interp_main = NULL;
|
||||
if (interp_head != NULL)
|
||||
Py_FatalError("PyInterpreterState_Delete: remaining subinterpreters");
|
||||
}
|
||||
HEAD_UNLOCK();
|
||||
PyMem_RawFree(interp);
|
||||
#ifdef WITH_THREAD
|
||||
|
@ -661,6 +671,12 @@ PyInterpreterState_Head(void)
|
|||
return interp_head;
|
||||
}
|
||||
|
||||
PyInterpreterState *
|
||||
PyInterpreterState_Main(void)
|
||||
{
|
||||
return interp_main;
|
||||
}
|
||||
|
||||
PyInterpreterState *
|
||||
PyInterpreterState_Next(PyInterpreterState *interp) {
|
||||
return interp->next;
|
||||
|
|
|
@ -1900,16 +1900,7 @@ static struct PyModuleDef sysmodule = {
|
|||
NULL
|
||||
};
|
||||
|
||||
PyObject *
|
||||
_PySys_Init(void)
|
||||
{
|
||||
PyObject *m, *sysdict, *version_info;
|
||||
int res;
|
||||
|
||||
m = PyModule_Create(&sysmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
sysdict = PyModule_GetDict(m);
|
||||
/* Updating the sys namespace, returning NULL pointer on error */
|
||||
#define SET_SYS_FROM_STRING_BORROW(key, value) \
|
||||
do { \
|
||||
PyObject *v = (value); \
|
||||
|
@ -1932,6 +1923,17 @@ _PySys_Init(void)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
PyObject *
|
||||
_PySys_BeginInit(void)
|
||||
{
|
||||
PyObject *m, *sysdict, *version_info;
|
||||
int res;
|
||||
|
||||
m = PyModule_Create(&sysmodule);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
sysdict = PyModule_GetDict(m);
|
||||
|
||||
/* Check that stdin is not a directory
|
||||
Using shell redirection, you can redirect stdin to a directory,
|
||||
crashing the Python interpreter. Catch this common mistake here
|
||||
|
@ -1963,25 +1965,12 @@ _PySys_Init(void)
|
|||
SET_SYS_FROM_STRING("_git",
|
||||
Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(),
|
||||
_Py_gitversion()));
|
||||
SET_SYS_FROM_STRING("dont_write_bytecode",
|
||||
PyBool_FromLong(Py_DontWriteBytecodeFlag));
|
||||
SET_SYS_FROM_STRING("api_version",
|
||||
PyLong_FromLong(PYTHON_API_VERSION));
|
||||
SET_SYS_FROM_STRING("copyright",
|
||||
PyUnicode_FromString(Py_GetCopyright()));
|
||||
SET_SYS_FROM_STRING("platform",
|
||||
PyUnicode_FromString(Py_GetPlatform()));
|
||||
SET_SYS_FROM_STRING("executable",
|
||||
PyUnicode_FromWideChar(
|
||||
Py_GetProgramFullPath(), -1));
|
||||
SET_SYS_FROM_STRING("prefix",
|
||||
PyUnicode_FromWideChar(Py_GetPrefix(), -1));
|
||||
SET_SYS_FROM_STRING("exec_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
|
||||
SET_SYS_FROM_STRING("base_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetPrefix(), -1));
|
||||
SET_SYS_FROM_STRING("base_exec_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
|
||||
SET_SYS_FROM_STRING("maxsize",
|
||||
PyLong_FromSsize_t(PY_SSIZE_T_MAX));
|
||||
SET_SYS_FROM_STRING("float_info",
|
||||
|
@ -2017,17 +2006,6 @@ _PySys_Init(void)
|
|||
SET_SYS_FROM_STRING("abiflags",
|
||||
PyUnicode_FromString(ABIFLAGS));
|
||||
#endif
|
||||
if (warnoptions == NULL) {
|
||||
warnoptions = PyList_New(0);
|
||||
if (warnoptions == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(warnoptions);
|
||||
}
|
||||
SET_SYS_FROM_STRING_BORROW("warnoptions", warnoptions);
|
||||
|
||||
SET_SYS_FROM_STRING_BORROW("_xoptions", get_xoptions());
|
||||
|
||||
/* version_info */
|
||||
if (VersionInfoType.tp_name == NULL) {
|
||||
|
@ -2052,13 +2030,8 @@ _PySys_Init(void)
|
|||
if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0)
|
||||
return NULL;
|
||||
}
|
||||
/* Set flags to their default values */
|
||||
SET_SYS_FROM_STRING("flags", make_flags());
|
||||
/* prevent user from creating new instances */
|
||||
FlagsType.tp_init = NULL;
|
||||
FlagsType.tp_new = NULL;
|
||||
res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
PyErr_Clear();
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
/* getwindowsversion */
|
||||
|
@ -2095,13 +2068,89 @@ _PySys_Init(void)
|
|||
}
|
||||
}
|
||||
|
||||
#undef SET_SYS_FROM_STRING
|
||||
#undef SET_SYS_FROM_STRING_BORROW
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef SET_SYS_FROM_STRING
|
||||
#undef SET_SYS_FROM_STRING_BORROW
|
||||
|
||||
/* Updating the sys namespace, returning integer error codes */
|
||||
#define SET_SYS_FROM_STRING_BORROW_INT_RESULT(key, value) \
|
||||
do { \
|
||||
PyObject *v = (value); \
|
||||
if (v == NULL) \
|
||||
return -1; \
|
||||
res = PyDict_SetItemString(sysdict, key, v); \
|
||||
if (res < 0) { \
|
||||
return res; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SET_SYS_FROM_STRING_INT_RESULT(key, value) \
|
||||
do { \
|
||||
PyObject *v = (value); \
|
||||
if (v == NULL) \
|
||||
return -1; \
|
||||
res = PyDict_SetItemString(sysdict, key, v); \
|
||||
Py_DECREF(v); \
|
||||
if (res < 0) { \
|
||||
return res; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
_PySys_EndInit(PyObject *sysdict)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* Set flags to their final values */
|
||||
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
|
||||
/* prevent user from creating new instances */
|
||||
FlagsType.tp_init = NULL;
|
||||
FlagsType.tp_new = NULL;
|
||||
res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
|
||||
if (res < 0) {
|
||||
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||
return res;
|
||||
}
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode",
|
||||
PyBool_FromLong(Py_DontWriteBytecodeFlag));
|
||||
SET_SYS_FROM_STRING_INT_RESULT("executable",
|
||||
PyUnicode_FromWideChar(
|
||||
Py_GetProgramFullPath(), -1));
|
||||
SET_SYS_FROM_STRING_INT_RESULT("prefix",
|
||||
PyUnicode_FromWideChar(Py_GetPrefix(), -1));
|
||||
SET_SYS_FROM_STRING_INT_RESULT("exec_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
|
||||
SET_SYS_FROM_STRING_INT_RESULT("base_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetPrefix(), -1));
|
||||
SET_SYS_FROM_STRING_INT_RESULT("base_exec_prefix",
|
||||
PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
|
||||
|
||||
if (warnoptions == NULL) {
|
||||
warnoptions = PyList_New(0);
|
||||
if (warnoptions == NULL)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(warnoptions);
|
||||
}
|
||||
SET_SYS_FROM_STRING_BORROW_INT_RESULT("warnoptions", warnoptions);
|
||||
|
||||
SET_SYS_FROM_STRING_BORROW_INT_RESULT("_xoptions", get_xoptions());
|
||||
|
||||
if (PyErr_Occurred())
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef SET_SYS_FROM_STRING_INT_RESULT
|
||||
#undef SET_SYS_FROM_STRING_BORROW_INT_RESULT
|
||||
|
||||
static PyObject *
|
||||
makepathobject(const wchar_t *path, wchar_t delim)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue